//游戏渲染
const { ccclass, property } = cc._decorator;
import GameCtrl from "./GameDataCtrl";
import { StepData } from "./GameData";
@ccclass
export default class Game extends cc.Component {

    @property(cc.Node)
    item: cc.Node = null;

    @property(cc.Node)
    content: cc.Node = null;

    @property(cc.RichText)
    scoreCmt: cc.RichText = null;

    @property(cc.Node)
    mask: cc.Node = null;

    @property(cc.Node)
    gameOver: cc.Node = null;

    @property(cc.Node)
    touchNd: cc.Node = null;

    @property(cc.Node)
    pop: cc.Node = null;

    gameCtrl: GameCtrl;
    itemPool: cc.NodePool = new cc.NodePool;
    isTouch: number = 0;
    startPos: cc.Vec2;
    endPos: cc.Vec2;
    // LIFE-CYCLE CALLBACKS:

    onLoad() {
        this.gameCtrl = GameCtrl.getInstance();
        this.gameCtrl.init(this.content, 10);
        //刷新ui
        this.updateConfigUi();
        this.resetGame();
        this.touchNd.on(cc.Node.EventType.TOUCH_START, this.touchStart, this);
        this.touchNd.on(cc.Node.EventType.TOUCH_CANCEL, this.touchCancel, this);
        this.touchNd.on(cc.Node.EventType.TOUCH_END, this.touchEnd, this);
        this.touchNd.on(cc.Node.EventType.TOUCH_MOVE, this.touchMove, this);
    }
    //刷新设置ui
    updateConfigUi() {
        let setting = this.pop.getChildByName('setting').getChildByName('bg');
        let config = this.gameCtrl.getUserConfig();
        for (let key in config) {
            let toggle = setting.getChildByName(key).getChildByName('toggle');
            if (toggle) {
                this.setToggle(toggle, config[key]);
            }
        }
    }
    touchStart(event: cc.Event.EventTouch) {
        if(this.isTouch == 0){
            this.isTouch = 1;
            this.startPos = event.getLocation();
        }
    }
    touchCancel(event: cc.Event.EventTouch) {
        this.isTouch = 0;
    }
    touchEnd(event: cc.Event.EventTouch) {
        this.isTouch = 0;
    }
    touchMove(event: cc.Event.EventTouch) {
        if (this.isTouch == 1) {
            this.endPos = event.getLocation();
            this.countMoveDir();
        }
    }
    //计算滑动方向
    countMoveDir() {
        let x = Math.abs(this.endPos.x - this.startPos.x);
        let y = Math.abs(this.endPos.y - this.startPos.y);
        if (x > 25) {
            if (this.endPos.x > this.startPos.x) {//右
                this.gameCtrl.move(1);
            } else {
                this.gameCtrl.move(0);
            }
            this.moveItem();
            this.isTouch = 2;
        } else if (y > 25) {
            if (this.endPos.y > this.startPos.y) {//上
                this.gameCtrl.move(2);
            } else {//下
                this.gameCtrl.move(3);
            }
            this.moveItem();
            this.isTouch = 2;
        }
    }
    //移动item
    moveItem() {
        let tweenArr = this.gameCtrl.getMoveData();
        if (tweenArr.length > 0) {
            this.mask.active = true;
            let promiseAll = [];
            tweenArr.forEach((moveData) => {
                let move = new Promise((s, r) => {
                    cc.tween(moveData.node)
                        .to(0.1, { opacity: moveData.Eopa, position: moveData.Epos })
                        .call(() => {
                            this.updateItem(moveData.node, {
                                x: moveData.Epos.x,
                                y: moveData.Epos.y,
                                num: moveData.num,
                            })
                            if (moveData.Eopa == 0) {
                                this.putItem(moveData.node);
                            }
                            s(true);
                        })
                        .start();
                })
                promiseAll.push(move);
            })
            Promise.all(promiseAll).then(() => {
                this.mask.active = false;
                let steps = this.gameCtrl.randomItem();
                steps.forEach((step)=>{
                    this.instantiateItem(step);
                });
                if (this.gameCtrl.checkGame()) {
                    this.gameOver.active = true;
                    this.mask.active = true;
                }
                this.updateScore();
            }).catch((err) => {
                cc.error(err);
            })
        }
    }
    //上一步
    onPre() {
        let historyCtrl = this.gameCtrl.getHistoryCtrlData();
        if (historyCtrl.length > 0) {
            this.gameCtrl.onPre();
            this.putAllItem();
            this.updateScore();
            this.updateBoard();
            this.gameOver.active = false;
            this.mask.active = false;
        }
    }
    //重新开始游戏
    resetGame() {
        this.gameCtrl.reset();
        this.putAllItem();
        this.updateScore();
        this.updateBoard();
        this.gameOver.active = false;
        this.mask.active = false;
    }
    //生成盘面
    updateBoard() {
        let arr = this.gameCtrl.getAllStep();
        arr.forEach((step) => {
            this.instantiateItem(step);
        })
    }
    //生成一个item
    instantiateItem(step: StepData) {
        if (step.num > 0 || step.num == 'X') {//有值
            let item = this.getItem();
            step.node = item;
            item.setParent(this.content);
            this.updateItem(item, step);
        }
    }
    //刷新 item
    updateItem(item: cc.Node, step) {
        item.active = true;
        item.getChildByName('num').getComponent(cc.Label).string = step.num;
        item.x = step.x;
        item.y = step.y;
        item.opacity = 255;
        let color = this.gameCtrl.getItemColor(step.num);
        item.getChildByName('bg').color = cc.color(color);
    }
    //得到一个item
    getItem() {
        let item = this.itemPool.get();
        if (!item) {
            item = cc.instantiate(this.item);
        }
        return item;
    }
    //回收所有item
    putAllItem() {
        for (let i = this.content.childrenCount - 1; i >= 0; i--) {
            this.putItem(this.content.children[i]);
        }
    }
    //回收一个item
    putItem(item: cc.Node) {
        this.itemPool.put(item);
    }
    //刷新成绩
    updateScore() {
        let hScore = this.gameCtrl.getHistoryScore();
        let cScore = this.gameCtrl.getCurScore();
        let str = `历史最高：${hScore}\n当前分数：${cScore}`;
        this.scoreCmt.string = str;
    }
    onExit() {
        cc.game.end();
    }
    //保存进度
    saveGame() {
        this.gameCtrl.saveGameData();
        this.onExit();
    }
    //退出游戏
    onClose() {
        if (!this.gameOver.active) {
            this.showPopName(null, 'tipBox');
        } else {
            this.onExit();
        }
    }
    //显示弹窗页面
    showPopName(event: cc.Button, name: string | boolean) {
        if (name) {
            this.pop.children.forEach((node) => {
                node.active = node.name == 'mask' || node.name == name;
            });
            this.pop.active = true;
            this.pop.opacity = 0;
            let node = this.pop.getChildByName(name as string);
            node.scale = 0;
            cc.tween(this.pop)
                .to(0.15, { opacity: 255 })
                .start();
            cc.tween(node)
                .to(0.15, { scale: 1 })
                .start();
        } else {
            this.pop.active = false;
        }
    }

    setToggle(toggle: cc.Node, bool: boolean) {
        if (bool != toggle['isCheck']) {
            toggle['isCheck'] = bool;
            let content = toggle.getChildByName('center');
            let check = content.getChildByName('check');
            let checkCenter = check.getChildByName('mask');
            let mask = content.getChildByName('mask').getComponent(cc.Sprite);
            cc.Tween.stopAllByTarget(check);
            cc.Tween.stopAllByTarget(mask);
            cc.Tween.stopAllByTarget(checkCenter);
            if (bool) {
                cc.tween(check)
                    .to(0.1, { color: cc.color(87, 174, 127), position: cc.v3(content.width / 2 - check.width / 2, 0, 0) })
                    .start();
                cc.tween(mask)
                    .to(0.1, { fillRange: 1 })
                    .start();
                cc.tween(checkCenter)
                    .to(0.1, { color: cc.color(110, 205, 154) })
                    .start();
            } else {
                cc.tween(check)
                    .to(0.1, { color: cc.color(190, 100, 100), position: cc.v3(-content.width / 2 + check.width / 2, 0, 0) })
                    .start();
                cc.tween(mask)
                    .to(0.1, { fillRange: 0 })
                    .start();
                cc.tween(checkCenter)
                    .to(0.1, { color: cc.color(215, 106, 106) })
                    .start();
            }
        }
    }
    onTouchToggle(event: cc.Button) {
        let node = event.target;
        let bool = !node['isCheck'];
        this.setToggle(node, bool);
        let config = this.gameCtrl.getUserConfig();
        config[node.parent.name] = bool;
        this.gameCtrl.saveUserConfig();
    }

    // update (dt) {}
}
